
# ==========================================================================#
#                                   子线程
# 功能：创建socket套接字
#      创建服务器线程（监听客户端连接）
#      关闭服务器
#      显示当前客户端数量
# ==========================================================================#
import json
import socket
import time

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QMessageBox

from socket_accept import Server_Thread
import global_var

class Thread(QThread):
    open_server = pyqtSignal(str)
    close_server = pyqtSignal()
    data_signal = pyqtSignal(str)

    # 传信号回主线程UI

    def __init__(self, mainui, robot_data, move_signal):
        super().__init__()
        self.socket_class = None
        self.server = None
        self.mainui = mainui
        self.robot_data = robot_data    # UI主线程信号（客户端数据）
        self.move_signal = move_signal  # UI主线程信号（运动控制）
        self.open_server.connect(self.Open_TcpServer)
        self.close_server.connect(self.Close_TcpServer)
        self.data_signal.connect(self.Data_Handle)
        self.move_signal.connect(self.Move_Handle)

        self.move_data = {}   # 运动控制信息

    # 处理运动控制数据
    def Move_Handle(self, move_data):
        self.move_data = json.loads(move_data)
        print("运动控制：", self.move_data.get("move"))

    # 处理客户端数据
    def Data_Handle(self, client_data):
        self.robot_data.emit(client_data)

    # 创建TCP服务器，使用socket套接字
    def Open_TcpServer(self, server_options):
        # 将json字符串转换为自定（之前的类型格式，这里是字典）
        server_options = json.loads(server_options)
        ip = server_options.get("ip")
        port = server_options.get("port")
        listen_max = server_options.get("listen_max")
        print('1.子线程收到信号:', server_options)
        # ================ 创建socket套接字 ================#
        # 创建socket
        # AF_INET:表示使用IP协议，SOCK_STREAM:表示使用TCP协议
        try:
            self.listenSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.listenSocket.bind((str(ip), int(port)))
            self.listenSocket.listen(int(listen_max))

            # ================ 创建服务器线程（客户端连接） ================#
            self.server = Server_Thread(self.listenSocket, self.data_signal)
            self.server.start()

            # ================ 更改按钮和编辑框 ================#
            self.mainui.server_pushButton.setText('关闭')
            # 编辑框设置不可编辑
            self.mainui.comboBox.setEditable(False)
            self.mainui.lineEdit_2.setEnabled(False)
            self.mainui.lineEdit_3.setEnabled(False)
            # 起始位置按钮有效
            self.mainui.start_pushButton.setEnabled(True)
        except:
            QMessageBox.information(None, "", "服务器创建失败，可能请求的地址无效", QMessageBox.Ok)
            pass

    # 关闭TCP服务器
    def Close_TcpServer(self):
        print('收到关闭服务器命令')
        # 循环列表，关闭socket和数据收发线程
        for i in range(len(global_var.get_client_addrs())):
            global_var.get_one_clientsockets(i).close()
            global_var.get_one_Thread_recv_send_list(i).terminate()  # 关闭客户端数据收发线程
        global_var.clear_clientsockets()
        global_var.clear_Thread_recv_send_list()
        global_var.clear_client_addrs()
        global_var.set_client_num(0)
        global_var.set_connect_change(True)
        print('服务器关闭')
        self.listenSocket.close()  # 关闭socket对象
        self.server.terminate()  # 强制退出服务器线程
        self.mainui.start_pushButton.setText("确定")

    def run(self):
        print('子线程正在运行......')
        move = None
        while True:
            time.sleep(0.02)
            # ======= 当客户端数量变化时改变label_4显示内容 ======= #
            if global_var.get_connect_change():
                global_var.set_connect_change(False)
                self.mainui.label_4.setText(str(global_var.get_client_num()))

            # ======= 获取要控制的小车ID ======= #
            client_id = self.mainui.comboBox_2.currentText()
            try:
                if self.move_data.get("move") == "up":
                    move = "up"
                elif self.move_data.get("move") == "down":
                    move = "down"
                elif self.move_data.get("move") == "left":
                    move = "left"
                elif self.move_data.get("move") == "right":
                    move = "right"
                elif self.move_data.get("move") == "released":
                    move = "released"
                    self.move_data = None
            except:
                pass
            if move:
                print(move)
                try:
                    global_var.get_one_clientsockets(int(client_id) - 1).send(
                        json.dumps({"header": "move", "move": move}).encode())
                except:
                    pass
                if move == "released":
                    move = None
